from datetime import datetime

from flask import current_app, jsonify
from flask import g
from flask import request

from ihome import db, sr
from ihome.models import House, Order
from ihome.modules.api import api_blu
from ihome.utils.common import check
from ihome.utils.response_code import RET, error_map


# 订单创建
@api_blu.route('/orders', methods=['POST'])
@check
def create_order():
    # 接受参数
    house_id = request.json.get('house_id')
    start_date = request.json.get('start_date')
    end_date = request.json.get('end_date')
    user_id = g.user.id

    if not all([house_id, start_date, end_date]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    # 校验是否存在房子
    try:
        house = House.query.get(house_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])
    if not house:
        return jsonify(errno=RET.NODATA, errmsg=error_map[RET.NODATA])

    try:
        start_date = datetime.strptime(start_date, '%Y-%m-%d')
        end_date = datetime.strptime(end_date, '%Y-%m-%d')
        assert start_date < end_date
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    # todo:判断当前房子的房主是否是当前房子的房东
    if house.user_id == user_id:
        return jsonify(errno=RET.ROLEERR, errmsg=error_map[RET.ROLEERR])

    # todo:查询是否有冲突的订单,先查询冲突的订单(查询订单中的该房子的日期冲突的),判断是否有
    try:
        filter_list = [Order.house_id == house_id, Order.begin_date < end_date, Order.end_date > start_date]
        count = Order.query.filter(*filter_list).count()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])
    if count:
        return jsonify(errno=RET.DATAERR, errmsg=error_map[RET.DATAERR])

    # 项订单表中添加一条记录
    order = Order()
    order.user_id = user_id
    order.house_id = house_id
    order.begin_date = start_date
    order.end_date = end_date
    order.days = (end_date - start_date).days
    order.house_price = house.price
    order.amount = (order.days) * (order.house_price)
    db.session.add(order)
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])

    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK], data={'order_id': order.id})


# 获取订单列表
@api_blu.route('/orders', methods=['GET'])
@check
def get_order_list():
    # 查询订单返回json
    # 接受数据
    role = request.args.get('role')
    user = g.user

    if not role:
        return jsonify(errno=RET.NODATA, errmsg=error_map[RET.NODATA])

    try:
        if role == 'landlord':
            # 先查询属于自己的房子
            houses = House.query.filter(House.user_id == user.id).all()
            houses_ids = [house.id for house in houses]
            # 查询订单中自己的房子
            orders = Order.query.filter(Order.house_id.in_(houses_ids)).order_by(Order.create_time.desc()).all()
        else:
            orders = Order.query.filter(Order.user_id == user.id).order_by(Order.create_time.desc()).all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])

    if orders:
        orders = [order.to_dict() for order in orders]

    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK], data={'orders': orders})


# 接单和拒单
@api_blu.route('/orders', methods=['PUT'])
@check
def handle_orders():
    # 接收数据
    action = request.json.get('action')
    order_id = request.json.get('order_id')

    user = g.user

    # 校验数据
    if not all([action, order_id]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    # 判断是否存在该订单
    try:
        order = Order.query.filter(Order.id == order_id, Order.status == 'WAIT_ACCEPT').first()
        house = order.house
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])

    if not order or house.user_id != user.id:
        return jsonify(errno=RET.PARAMERR, errmsg='只能修改自己的定单')

    # 判断action
    if action not in ['accept', 'reject']:
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    # 判断该订单的房子是不是该房东的
    # if order.house_id not in [house.id for house in user.houses]:
    #     print('*' * 50)
    #     return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    if action == 'accept':
        # 修改订单状态
        order.status = 'WAIT_PAYMENT'
    elif action == 'reject':
        order.status = 'REJECTED'
        reason = request.json.get('reason')
        if not reason:
            return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
        else:
            order.comment = reason
    try:
        db.session.add(order)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])

    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK])


# 评价订单
@api_blu.route('/orders/comment', methods=['PUT'])
@check
def comment_publish():
    # 接受参数
    comment = request.json.get('comment')
    order_id = request.json.get('order_id')

    user = g.user

    # 校验参数
    if not all([comment, order_id]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    try:
        order_id = int(order_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    # 查询是否存在该订单
    try:
        # order = Order.query.get(order_id)
        order = Order.query.filter(Order.id == order_id, Order.status == 'WAIT_COMMENT', Order.user_id == user.id).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])

    if not order:
        return jsonify(errno=RET.NODATA, errmsg=error_map[RET.NODATA])

    house = order.house

    # todo:是一组事物,如果一个失败,其余一起回滚
    try:
        # 修改订单
        order.comment = comment

        # 房屋的订单数增加
        house.order_count += 1

        # 修改订单状态
        order.status = 'COMPLETE'

        db.session.add_all([order, house])
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])

    # 删除redis中房屋详情页中的缓存
    try:
        sr.delete('house_info_%s' % order.house.id)
    except Exception as e:
        current_app.logger.error(e)

    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK])
